﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace ProModel.ApplicationFramework.Silverlight
{
    #region ModalControl Class

    /// <summary>
    /// The ModalControl class can be used to render any UserControl modally. Once
    /// rendered the UserControl can be moved by mouse dragging, but not other features are
    /// supported.
    /// </summary>
    /// <remarks>
    /// The ModalControl class is typically for use UserControls looking to take a
    /// completely custom approach to the modal dialog appearance while leveraging existing
    /// modal rendering support, or for use with controls such as progress bars, etc.
    /// </remarks>
    /// <example>
    /// 	<para><font color="blue" size="2"><font color="blue" size="2"><font color="blue" size="2"><font color="blue" size="2">public</font></font>
    /// 				<font color="blue" size="2"><font color="blue" size="2">void</font></font>
    /// 				<font size="2">ShowModal(</font><font color="#F14A12" size="2"><font color="#F14A12" size="2">DialogClose</font></font>
    /// 				<font size="2">callback ,</font>
    /// 				<font color="#F95100" size="2"><font color="#F95100" size="2">Panel</font></font>
    /// 				<font size="2">panel)</font></font></font></para>
    /// 	<para><font color="blue" size="2"><font color="blue" size="2"><font size="2">{</font></font></font></para>
    /// 	<para><font color="blue" size="2"><font color="blue" size="2"><font color="blue" size="2"><font color="blue" size="2">bool</font></font>
    /// 				<font size="2">useCanvasPainting =</font>
    /// 				<font color="blue" size="2"><font color="blue" size="2">true</font></font><font size="2">;</font></font></font></para>
    /// 	<para><font color="blue" size="2"><font color="blue" size="2"><font color="#F95100" size="2"><font color="#F95100" size="2">ModalControl</font></font>
    /// 				<font size="2">wmc =</font>
    /// 				<font color="blue" size="2"><font color="blue" size="2">new</font></font>
    /// 				<font color="#F95100" size="2"><font color="#F95100" size="2">ModalControl</font></font><font size="2">(</font><font color="blue" size="2"><font color="blue" size="2">new</font></font>
    /// 				<font color="#F14A12" size="2"><font color="#F14A12" size="2">DialogClose</font></font><font size="2">(OnDialogClosed));</font></font></font></para>
    /// 	<para><font color="blue" size="2"><font color="blue" size="2"><font color="#F95100" size="2"><font color="#F95100" size="2">TestUserControl</font></font>
    /// 				<font size="2">tc =</font>
    /// 				<font color="blue" size="2"><font color="blue" size="2">new</font></font>
    /// 				<font color="#F95100" size="2"><font color="#F95100" size="2">TestUserControl</font></font><font size="2">();</font></font></font></para>
    /// 	<para><font color="blue" size="2"><font color="blue" size="2"><font size="2">wmc.HostedControl = tc;</font></font></font></para>
    /// 	<para><font color="blue" size="2"><font color="blue" size="2"><font size="2">wmc.ShowModal(panel, useCanvasPainting,</font>
    /// 				<font color="blue" size="2"><font color="blue" size="2">new</font></font>
    /// 				<font color="#F14A12" size="2"><font color="#F14A12" size="2">Size</font></font><font size="2">(tc.MinWidth,
    ///     tc.MinHeight));</font></font></font></para>
    /// 	<para><font color="blue" size="2"><font color="blue" size="2"><font size="2">}</font></font></font></para>
    /// 	<para></para>
    /// 	<para><font color="blue" size="2"><font color="blue" size="2">bool</font></font><font size="2">OnDialogClosed(</font><font color="blue" size="2"><font color="blue" size="2">object</font></font><font size="2">sender,</font><font color="#F14A12" size="2"><font color="#F14A12" size="2">DialogExit</font></font><font size="2">e)</font></para>
    /// 	<para><font size="2">{</font></para>
    /// 	<para><font size="2">_tbResult.Text = e.ToString();</font></para>
    /// 	<para><font color="blue" size="2"><font color="blue" size="2">return</font></font><font color="blue" size="2"><font color="blue" size="2">true</font></font><font size="2">;</font></para>
    /// 	<para><font size="2">}</font></para>
    /// </example>
    public partial class ModalControl : UserControl, IModal
    {
        #region Fields/Properties

        private DialogClose _callback;

        private Modal _modal;
        internal Modal Modal
        {
            get { return _modal; }
        }

        private ModalHost _host;
        internal ModalHost Host
        {
            get { return _host; }
        }

        UserControl _userCtrl;
        public UserControl UserCtrl
        {
            get { return _userCtrl; }
            set
            {
                _userCtrl = value;

                if (_userCtrl != null)
                {
                    _userPanel.Children.Clear();
                    _userPanel.Children.Add(_userCtrl);
                }
            }
        }

        #region IModal Members

        UserControl _hostedControl;
        public UserControl HostedControl
        {
            get
            {
                return _hostedControl;
            }
            set
            {
                _hostedControl = value;

                if (_hostedControl != null)
                {
                    _userPanel.Children.Clear();
                    _userPanel.Children.Add(_hostedControl);
                }
            }
        }

        #endregion

        #endregion

        #region Construction

        public ModalControl()
        {
            InitializeComponent();

            InitWindowedModal(null);
        }

        /// <summary>Creates a ModalControl instance with a specified DialogClose handler.</summary>
        public ModalControl(DialogClose callback)
        {
            InitializeComponent();

            InitWindowedModal(callback);
        }

        private void InitWindowedModal(DialogClose callback)
        {
            _modal = new Modal();
            _modal.PopupCreated += new EventHandler(PopupCreated);
            _callback = callback;
        }

        #endregion

        #region Events

        void PopupCreated(object sender, EventArgs e)
        {
            _host = _modal.Host as ModalHost;
        }

        #endregion

        #region Window Methods

        /// <summary>Causes the hosted UserControl to be displayed modally.</summary>
        /// <example>
        /// 	<para><font color="blue" size="2"><font color="blue" size="2">public</font></font>
        /// 		<font color="blue" size="2"><font color="blue" size="2">void</font></font>
        /// 		<font size="2">ShowModal(</font><font color="#F14A12" size="2"><font color="#F14A12" size="2">DialogClose</font></font>
        /// 		<font size="2">oCallback,</font>
        /// 		<font color="#F95100" size="2"><font color="#F95100" size="2">Panel</font></font>
        /// 		<font size="2">panel)</font></para>
        /// 	<para><font size="2">{</font></para>
        /// 	<para><font color="blue" size="2"><font color="blue" size="2">bool</font></font>
        /// 		<font size="2">useCanvasPainting =</font>
        /// 		<font color="blue" size="2"><font color="blue" size="2">true</font></font><font size="2">;</font></para>
        /// 	<para><font color="#F95100" size="2"><font color="#F95100" size="2">ModalControl</font></font>
        /// 		<font size="2">wmc =</font>
        /// 		<font color="blue" size="2"><font color="blue" size="2">new</font></font>
        /// 		<font color="#F95100" size="2"><font color="#F95100" size="2">ModalControl</font></font><font size="2">(</font><font color="blue" size="2"><font color="blue" size="2">new</font></font>
        /// 		<font color="#F14A12" size="2"><font color="#F14A12" size="2">DialogClose</font></font><font size="2">(OnDialogClosed));</font></para>
        /// 	<para><font color="#F95100" size="2"><font color="#F95100" size="2">TestUserControl</font></font>
        /// 		<font size="2">tc =</font>
        /// 		<font color="blue" size="2"><font color="blue" size="2">new</font></font>
        /// 		<font color="#F95100" size="2"><font color="#F95100" size="2">TestUserControl</font></font><font size="2">();</font></para>
        /// 	<para><font size="2">wmc.HostedControl = tc;</font></para>
        /// 	<para><font size="2">wmc.ShowModal(panel, useCanvasPainting,</font>
        /// 		<font color="blue" size="2"><font color="blue" size="2">new</font></font>
        /// 		<font color="#F14A12" size="2"><font color="#F14A12" size="2">Size</font></font><font size="2">(tc.MinWidth, tc.MinHeight));</font></para>
        /// 	<para><font size="2">}</font></para>
        /// </example>
        /// <param name="parent">The FrameworkElement that parents the hosted UserControl.</param>
        /// <param name="useCanvasPainting">
        /// Causes the browser area not covered by the modal to be painted over with a
        /// visible transparency.
        /// </param>
        /// <param name="minSize">
        /// Specifies the minimum height and width to be used with the hosted UserControl. 
        /// Note, this will be the starting display size for the hosted control.
        /// </param>
        public bool ShowModal(Panel parent, bool useCanvasPainting, Size minSize)
        {
            bool success = _modal.ShowModal(parent, this as IModal, useCanvasPainting);
            
            if (success)
            {
               SetInnerControlBounds(minSize);  
            } 

            return success;
        }

        private void SetInnerControlBounds(Size minSize)
        {
            this.Width = minSize.Width;
            this.Height = minSize.Height;
            this.MinWidth = this.Width;
            this.MinHeight = this.Height;
        }

        private void SetWindowSize(double width, double height)
        {
            this.Width = width;
            this.Height = height;
        }

        #endregion
    }

    #endregion
}
